package com.wtf.dsp.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wtf.dsp.admin.util.MapperXmlUtil;
import com.wtf.dsp.admin.entity.WtfDspMapper;
import com.wtf.dsp.admin.entity.WtfDspSql;
import com.wtf.dsp.admin.enums.CommonErrorEnum;
import com.wtf.dsp.admin.enums.SqlMybatisXml;
import com.wtf.dsp.admin.exception.WtfDspException;
import com.wtf.dsp.admin.core.executor.WtfDynamicDataSourceMybatisConfigExecutor;
import com.wtf.dsp.admin.mapper.WtfDspMapperMapper;
import com.wtf.dsp.admin.mapper.WtfDspSqlMapper;
import com.wtf.dsp.admin.model.dto.MnsAddDTO;
import com.wtf.dsp.admin.model.dto.MnsDelDTO;
import com.wtf.dsp.admin.model.dto.MnsListDTO;
import com.wtf.dsp.admin.model.dto.MnsPageDTO;
import com.wtf.dsp.admin.model.vo.MnsVO;
import com.wtf.dsp.admin.service.MapperService;
import com.wtf.dsp.core.constant.NsConstant;
import com.wtf.dsp.core.enums.SqlType;
import com.wtf.dsp.core.util.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: DsMapperServiceImpl
 * Description:
 * date: 2023/7/11 9:58
 *
 * @author linhuanyou
 * @version 1.0
 */
@Slf4j
@Service
public class MapperServiceImpl implements MapperService {

    @Resource
    private WtfDspMapperMapper wtfDspMapperMapper;

    @Resource
    private WtfDspSqlMapper wtfDspSqlMapper;

    @Autowired
    private WtfDynamicDataSourceMybatisConfigExecutor wtfDynamicDataSourceMybatisConfigExecutor;

    @Override
    public PageUtils page(MnsPageDTO mnsPageDTO) {
        Page<?> page = PageHelper.startPage(mnsPageDTO.getPage(), mnsPageDTO.getLimit());
        List<MnsVO> dmVOS = getDmVOS(mnsPageDTO);
        return new PageUtils(dmVOS, (int) page.getTotal(), mnsPageDTO.getLimit(), mnsPageDTO.getPage());
    }

    @Override
    public List<MnsVO> getDmVOS(MnsPageDTO mnsPageDTO) {
        return wtfDspMapperMapper.list(mnsPageDTO).stream().map(e -> {
                LambdaQueryWrapper<WtfDspSql> wtfMapperSqlLambdaQueryWrapper = new LambdaQueryWrapper<>();
                wtfMapperSqlLambdaQueryWrapper.eq(WtfDspSql::getNs,e.getNs());
                wtfMapperSqlLambdaQueryWrapper.eq(WtfDspSql::getDs,e.getDs());
                wtfMapperSqlLambdaQueryWrapper.eq(WtfDspSql::getMns,e.getMns());
                List<String> sqlList = wtfDspSqlMapper.selectList(wtfMapperSqlLambdaQueryWrapper).stream().map(e1->{
                    return SqlMybatisXml.obtainSqlstatementXml(SqlType.valueOf(e1.getSqlType()),e1.getSqlId(),e1.getSqlStatement());
                }).collect(Collectors.toList());
                e.setXml(MapperXmlUtil.mapperXmlStr(NsConstant.mapperNamespace(e.getNs(), e.getDs(),e.getMns()),sqlList));
                return e;
            }).collect(Collectors.toList());
    }

    @Override
    public List<MnsVO> list(MnsListDTO mnsListDTO) {
        MnsPageDTO dmPageDTO = new MnsPageDTO();
        dmPageDTO.setNs(mnsListDTO.getNs());
        dmPageDTO.setDs(mnsListDTO.getDs());
        List<MnsVO> dmVOS = getDmVOS(dmPageDTO);
        return dmVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int add(MnsAddDTO mnsAddDTO) {
        LambdaQueryWrapper<WtfDspMapper> wtfMapperDsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wtfMapperDsLambdaQueryWrapper.eq(WtfDspMapper::getNs, mnsAddDTO.getNs());
        wtfMapperDsLambdaQueryWrapper.eq(WtfDspMapper::getDs, mnsAddDTO.getDs());
        wtfMapperDsLambdaQueryWrapper.eq(WtfDspMapper::getMns, mnsAddDTO.getMns());
        int count = wtfDspMapperMapper.selectCount(wtfMapperDsLambdaQueryWrapper);
        if(count > 0){
            throw new WtfDspException(CommonErrorEnum.MAPPER_EXIST);
        }
        WtfDspMapper wtfMapperDs = new WtfDspMapper();
        wtfMapperDs.setNs(mnsAddDTO.getNs());
        wtfMapperDs.setDs(mnsAddDTO.getDs());
        wtfMapperDs.setMns(mnsAddDTO.getMns());
        int insert = wtfDspMapperMapper.insert(wtfMapperDs);
        if(insert > 0){
            wtfDynamicDataSourceMybatisConfigExecutor.refreshMapperSqlConfig(mnsAddDTO.getNs(), mnsAddDTO.getDs(), mnsAddDTO.getMns());
        }
        return insert;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int remove(MnsDelDTO mnsDelDTO) {
        LambdaQueryWrapper<WtfDspSql> wtfDspSqlLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wtfDspSqlLambdaQueryWrapper.eq(WtfDspSql::getNs, mnsDelDTO.getNs());
        wtfDspSqlLambdaQueryWrapper.eq(WtfDspSql::getDs, mnsDelDTO.getDs());
        wtfDspSqlLambdaQueryWrapper.in(WtfDspSql::getMns, mnsDelDTO.getMnss());
        int deleteSql = wtfDspSqlMapper.delete(wtfDspSqlLambdaQueryWrapper);
        LambdaQueryWrapper<WtfDspMapper> wtfDspMapperLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wtfDspMapperLambdaQueryWrapper.eq(WtfDspMapper::getNs, mnsDelDTO.getNs());
        wtfDspMapperLambdaQueryWrapper.eq(WtfDspMapper::getDs, mnsDelDTO.getDs());
        wtfDspMapperLambdaQueryWrapper.in(WtfDspMapper::getMns, mnsDelDTO.getMnss());
        int deleteMapper = wtfDspMapperMapper.delete(wtfDspMapperLambdaQueryWrapper);
        if(deleteMapper > 0){
            wtfDynamicDataSourceMybatisConfigExecutor.refreshMapperSqlConfig(mnsDelDTO.getNs(), mnsDelDTO.getDs(),null);
        }
        return deleteMapper;
    }

}
